home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume10 / complex-lib < prev    next >
Encoding:
Text File  |  1987-07-14  |  24.2 KB  |  1,106 lines

  1. Path: uunet!rs
  2. From: rs@uunet.UU.NET (Rich Salz)
  3. Newsgroups: comp.sources.unix
  4. Subject: v10i056:  Complex arithmetic library
  5. Message-ID: <647@uunet.UU.NET>
  6. Date: 16 Jul 87 00:12:15 GMT
  7. Organization: UUNET Communications Services, Arlington, VA
  8. Lines: 1095
  9. Approved: rs@uunet.UU.NET
  10.  
  11. Submitted-by: gwyn@brl.arpa (Doug Gwyn)
  12. Posting-Number: Volume 10, Issue 56
  13. Archive-name: complex-lib
  14.  
  15. [  Here is a package to do complex arithmetic; blame me for the Makefile.
  16.     --r$  ]
  17.  
  18. #! /bin/sh
  19. # This is a shell archive.  Remove anything before this line, then unpack
  20. # it by saving it into a file and typing "sh file".  To overwrite existing
  21. # files, type "sh file -c".  You can also feed this as standard input via
  22. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  23. # will see the following message at the end:
  24. #        "End of shell archive."
  25. # Contents:  Makefile complex.3 complex.h cx_test.c cxadd.c cxampl.c
  26. #   cxconj.c cxcons.c cxcopy.c cxdiv.c cxmul.c cxphas.c cxphsr.c
  27. #   cxscal.c cxsqrt.c cxsub.c
  28. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  29. if test -f Makefile -a "${1}" != "-c" ; then 
  30.   echo shar: Will not over-write existing file \"Makefile\"
  31. else
  32. echo shar: Extracting \"Makefile\" \(395 characters\)
  33. sed "s/^X//" >Makefile <<'END_OF_Makefile'
  34. XALL=complex.3 complex.h libcomplex.a
  35. XOBJS=\
  36. X    cxadd.o cxampl.o cxconj.o cxcons.o cxcopy.o cxdiv.o cxmul.o \
  37. X    cxphas.o cxphsr.o cxscal.o cxsqrt.o cxsub.o
  38. X
  39. Xall:    $(ALL)
  40. X
  41. Xinstall:    $(ALL)
  42. X    @echo install $(ALL) according to local convention.
  43. X
  44. Xcx_test:    cx_test.c libcomplex.a
  45. X    $(CC) $(CFLAGS) -o cx_test cx_test.c libcomplex.a
  46. X
  47. Xlibcomplex.a:    $(OBJS)
  48. X    ar r libcomplex.a $(OBJS)
  49. X
  50. X$(OBJS):    complex.h
  51. END_OF_Makefile
  52. if test 395 -ne `wc -c <Makefile`; then
  53.     echo shar: \"Makefile\" unpacked with wrong size!
  54. fi
  55. # end of overwriting check
  56. fi
  57. if test -f complex.3 -a "${1}" != "-c" ; then 
  58.   echo shar: Will not over-write existing file \"complex.3\"
  59. else
  60. echo shar: Extracting \"complex.3\" \(5830 characters\)
  61. sed "s/^X//" >complex.3 <<'END_OF_complex.3'
  62. X'\" e
  63. X.TH COMPLEX 3V LOCAL
  64. X'\"    last edit:    86/02/03    D A Gwyn
  65. X'\"    SCCS ID:    @(#)complex.3    1.2 (modified for public version)
  66. X.EQ
  67. Xdelim @@
  68. X.EN
  69. X.SH NAME
  70. Xcomplex \- complex arithmetic operations
  71. X.SH SYNOPSIS
  72. X.B
  73. X#include <complex.h>    /* assuming appropriate cc \-I option */
  74. X.br
  75. X/* All the following functions are declared in this header file. */
  76. X.P
  77. X.B complex *CxAdd(ap,bp);
  78. X.br
  79. X.B complex *ap, *bp;
  80. X.P
  81. X.B complex *CxSub(ap,bp);
  82. X.br
  83. X.B complex *ap, *bp;
  84. X.P
  85. X.B complex *CxMul(ap,bp);
  86. X.br
  87. X.B complex *ap, *bp;
  88. X.P
  89. X.B complex *CxDiv(ap,bp);
  90. X.br
  91. X.B complex *ap, *bp;
  92. X.P
  93. X.B complex *CxSqrt(cp);
  94. X.br
  95. X.B complex *cp;
  96. X.P
  97. X.B complex *CxScal(cp,\^s);
  98. X.br
  99. X.B complex *cp;
  100. X.br
  101. X.B double s;
  102. X.P
  103. X.B complex *CxNeg(cp);
  104. X.br
  105. X.B complex *cp;
  106. X.P
  107. X.B complex *CxConj(cp);
  108. X.br
  109. X.B complex *cp;
  110. X.P
  111. X.B complex *CxCopy(ap,bp);
  112. X.br
  113. X.B complex *ap, *bp;
  114. X.P
  115. X.B complex *CxCons(cp,\^r,\^i);
  116. X.br
  117. X.B complex *cp;
  118. X.br
  119. X.B double r, i;
  120. X.P
  121. X.B complex *CxPhsr(cp,m,p);
  122. X.br
  123. X.B complex *cp;
  124. X.br
  125. X.B double m, p;
  126. X.P
  127. X.B double CxReal(cp);
  128. X.br
  129. X.B complex *cp;
  130. X.P
  131. X.B double CxImag(cp);
  132. X.br
  133. X.B complex *cp;
  134. X.P
  135. X.B double CxAmpl(cp);
  136. X.br
  137. X.B complex *cp;
  138. X.P
  139. X.B double CxPhas(cp);
  140. X.br
  141. X.B complex *cp;
  142. X.P
  143. X.B complex *CxAllo(\ );
  144. X.P
  145. X.B void CxFree(cp);
  146. X.br
  147. X.B complex *cp;
  148. X.SH DESCRIPTION
  149. XThese routines perform arithmetic
  150. Xand other useful operations on complex numbers.
  151. XAn appropriate data structure
  152. X.B complex
  153. Xis defined in the header file;
  154. Xall access to
  155. X.B complex
  156. Xdata should be
  157. X.I via
  158. Xthese predefined functions.
  159. X(See
  160. X.SM HINTS
  161. Xfor further information.)
  162. X.P
  163. XIn the following descriptions,
  164. Xthe names
  165. X.IR a ,
  166. X.IR b ,
  167. Xand
  168. X.I c
  169. Xrepresent the
  170. X.B complex
  171. Xdata addressed by the corresponding pointers
  172. X.IR ap ,
  173. X.IR bp ,
  174. Xand
  175. X.IR cp .
  176. X.P
  177. X.I CxAdd\^
  178. Xadds
  179. X.I b
  180. Xto
  181. X.I a
  182. Xand returns a pointer to the result.
  183. X.P
  184. X.I CxSub
  185. Xsubtracts
  186. X.I b
  187. Xfrom
  188. X.I a
  189. Xand returns a pointer to the result.
  190. X.P
  191. X.I CxMul\^
  192. Xmultiplies
  193. X.I a
  194. Xby
  195. X.I b
  196. Xand returns a pointer to the result.
  197. X.P
  198. X.I CxDiv
  199. Xdivides
  200. X.I a
  201. Xby
  202. X.I b
  203. Xand returns a pointer to the result.
  204. XThe divisor must not be precisely zero.
  205. X.P
  206. X.I CxSqrt
  207. Xreplaces
  208. X.I c
  209. Xby the ``principal value'' of its square root
  210. X(one having a non-negative imaginary part)
  211. Xand returns a pointer to the result.
  212. X.P
  213. X.I CxScal\^
  214. Xmultiplies
  215. X.I c
  216. Xby the scalar
  217. X.I s
  218. Xand returns a pointer to the result.
  219. X.P
  220. X.I CxNeg
  221. Xnegates
  222. X.I c
  223. Xand returns a pointer to the result.
  224. X.P
  225. X.I CxConj
  226. Xconjugates
  227. X.I c
  228. Xand returns a pointer to the result.
  229. X.P
  230. X.I CxCopy
  231. Xassigns the value of
  232. X.I b
  233. Xto
  234. X.I a
  235. Xand returns a pointer to the result.
  236. X.P
  237. X.I CxCons
  238. Xconstructs the complex number
  239. X.I c
  240. Xfrom its real and imaginary parts
  241. X.I r
  242. Xand
  243. X.IR i ,
  244. Xrespectively,
  245. Xand returns a pointer to the result.
  246. X.P
  247. X.I CxPhsr
  248. Xconstructs the complex number
  249. X.I c
  250. Xfrom its ``phasor'' amplitude and phase (given in radians)
  251. X.I m
  252. Xand
  253. X.IR p ,
  254. Xrespectively,
  255. Xand returns a pointer to the result.
  256. X.P
  257. X.I CxReal\^
  258. Xreturns the real part of the complex number
  259. X.IR c .
  260. X.P
  261. X.I CxImag
  262. Xreturns the imaginary part of the complex number
  263. X.IR c .
  264. X.P
  265. X.I CxAmpl\^
  266. Xreturns the amplitude of the complex number
  267. X.IR c .
  268. X.P
  269. X.I CxPhas
  270. Xreturns the phase of the complex number
  271. X.IR c ,
  272. Xas radians in the range @(- pi , pi ]@.
  273. X.P
  274. X.I CxAllo
  275. Xallocates storage for a
  276. X.B complex
  277. Xdatum; it returns
  278. X.SM
  279. X.B NULL
  280. X(defined as 0 in
  281. X.BR <stdio.h> )
  282. Xif not enough storage is available.
  283. X.P
  284. X.I CxFree
  285. Xreleases storage previously allocated by
  286. X.IR CxAllo .
  287. XThe contents of such storage must not be used afterward.
  288. X.SH HINTS
  289. XThe
  290. X.B complex
  291. Xdata type consists of real and imaginary components;
  292. X.I CxReal\^
  293. Xand
  294. X.I CxImag
  295. Xare actually macros that access these components directly.
  296. XThis allows addresses of the components to be taken,
  297. Xas in the following \s-1EXAMPLE\s0.
  298. X.P
  299. XThe complex functions are designed to be nested;
  300. Xsee the following \s-1EXAMPLE\s0.
  301. XFor this reason,
  302. Xmany of them modify the contents of their first parameter.
  303. X.I CxCopy
  304. Xcan be used to create a ``working copy'' of
  305. X.B complex
  306. Xdata that would otherwise be modified.
  307. X.P
  308. XThe square-root function is inherently double-valued;
  309. Xin most applications, both roots should receive equal consideration.
  310. XThe second root is the negative of the ``principal value''.
  311. X.bp
  312. X.SH EXAMPLE
  313. XThe following program is compiled by the command
  314. X.br
  315. X    $ \fIcc \|\-I/usr/local/include \|example.c \|/usr/local/lib/libcomplex.a \|\-lm\fP
  316. X.br
  317. XIt reads in two complex vectors,
  318. Xthen computes and prints their inner product.
  319. X.sp
  320. X.P
  321. X    #include    <stdio.h>
  322. X.br
  323. X    #include    <complex.h>
  324. X.sp
  325. X    main( argc, argv )
  326. X.br
  327. X        int        argc;
  328. X.br
  329. X        char        *argv[\|];
  330. X.br
  331. X        {
  332. X.br
  333. X        int        n;        /* # elements in each array */
  334. X.br
  335. X        int        i;        /* indexes arrays */
  336. X.br
  337. X        complex        a[10], b[10];    /* input vectors */
  338. X.br
  339. X        complex        s;        /* accumulates scalar product */
  340. X.br
  341. X        complex        *c = CxAllo(\|);    /* holds cross-term */
  342. X.sp
  343. X        if ( c == NULL )
  344. X.br
  345. X            {
  346. X.br
  347. X            (void)fprintf( stderr, ``not enough memory\en'' );
  348. X.br
  349. X            return 1;
  350. X.br
  351. X            }
  352. X.br
  353. X        (void)printf( ``\enenter number of elements: '' );
  354. X.br
  355. X        (void)scanf( `` %d'', &n );
  356. X.br
  357. X        /* (There really should be some input validation here.) */
  358. X.br
  359. X        (void) printf( ``\enenter real, imaginary pairs for first array:\en'' );
  360. X.br
  361. X        for ( i = 0; i < n; ++i )
  362. X.br
  363. X            (void)scanf( `` %lg %lg'', &CxReal( &a[i] ), &CxImag( &a[i] ) );
  364. X.br
  365. X        (void)printf( ``\enenter real, imaginary pairs for second array:\en'' );
  366. X.br
  367. X        for ( i = 0; i < n; ++i )
  368. X.br
  369. X            (void)scanf( `` %lg %lg'', &CxReal( &b[i] ), &CxImag( &b[i] ) );
  370. X.br
  371. X        (void)CxCons( &s, 0.0, 0.0 );    /* initialize accumulator */
  372. X.br
  373. X        for ( i = 0; i < n; ++i )
  374. X.br
  375. X            (void)CxAdd( &s, CxMul( &a[i], CxConj( CxCopy( c, &b[i] ) ) ) );
  376. X.br
  377. X        (void)printf( ``\enproduct is (%g,%g)\en'', CxReal( &s ), CxImag( &s ) );
  378. X.br
  379. X        CxFree( c );
  380. X.br
  381. X        return 0;
  382. X.br
  383. X        }
  384. X.SH FILES
  385. X/usr/local/include/complex.h        header file containing definitions
  386. X.br
  387. X/usr/local/lib/libcomplex.a        complex run-time support library
  388. X.SH AUTHORS
  389. XDouglas A. Gwyn, BRL/VLD-VMB
  390. X.br
  391. XJeff Hanes, BRL/VLD-VMB (original version of
  392. X.IR CxSqrt\^ )
  393. END_OF_complex.3
  394. if test 5830 -ne `wc -c <complex.3`; then
  395.     echo shar: \"complex.3\" unpacked with wrong size!
  396. fi
  397. # end of overwriting check
  398. fi
  399. if test -f complex.h -a "${1}" != "-c" ; then 
  400.   echo shar: Will not over-write existing file \"complex.h\"
  401. else
  402. echo shar: Extracting \"complex.h\" \(966 characters\)
  403. sed "s/^X//" >complex.h <<'END_OF_complex.h'
  404. X/*
  405. X    <complex.h> -- definitions for complex arithmetic routines
  406. X
  407. X    last edit:    86/01/04    D A Gwyn
  408. X
  409. X    SCCS ID:    @(#)complex.h    1.1 (modified for public version)
  410. X*/
  411. X
  412. X/* "complex number" data type: */
  413. X
  414. Xtypedef struct
  415. X    {
  416. X    double        re;        /* real part */
  417. X    double        im;        /* imaginary part */
  418. X    }    complex;
  419. X
  420. X/* "The future is now": */
  421. X
  422. X#ifdef __STDC__    /* X3J11 */
  423. X#define    _CxGenPtr    void *        /* generic pointer type */
  424. X#else        /* K&R */
  425. X#define    _CxGenPtr    char *        /* generic pointer type */
  426. X#endif
  427. X
  428. X/* functions that are correctly done as macros: */
  429. X
  430. X#define    CxAllo()        ((complex *)malloc( sizeof (complex) ))
  431. X#define    CxFree( cp )        free( (_CxGenPtr)(cp) )
  432. X#define    CxNeg( cp )        CxScal( cp, -1.0 )
  433. X#define    CxReal( cp )        (cp)->re
  434. X#define    CxImag( cp )        (cp)->im
  435. X
  436. Xextern void        free();
  437. Xextern _CxGenPtr    malloc();
  438. X
  439. X/* library functions: */
  440. X
  441. Xextern double    CxAmpl(), CxPhas();
  442. Xextern complex    *CxAdd(), *CxConj(), *CxCons(), *CxCopy(), *CxDiv(),
  443. X        *CxMul(), *CxPhsr(), *CxScal(), *CxSqrt(), *CxSub();
  444. END_OF_complex.h
  445. if test 966 -ne `wc -c <complex.h`; then
  446.     echo shar: \"complex.h\" unpacked with wrong size!
  447. fi
  448. # end of overwriting check
  449. fi
  450. if test -f cx_test.c -a "${1}" != "-c" ; then 
  451.   echo shar: Will not over-write existing file \"cx_test.c\"
  452. else
  453. echo shar: Extracting \"cx_test.c\" \(4250 characters\)
  454. sed "s/^X//" >cx_test.c <<'END_OF_cx_test.c'
  455. X/*
  456. X    ctest -- complex arithmetic test
  457. X
  458. X    last edit:    86/01/04    D A Gwyn
  459. X
  460. X    SCCS ID:    @(#)cx_test.c    1.1 (modified for public version)
  461. X*/
  462. X
  463. X#include    <stdio.h>
  464. X#include    <math.h>
  465. X
  466. X#include    <complex.h>
  467. X
  468. X#define DEGRAD    57.2957795130823208767981548141051703324054724665642
  469. X                    /* degrees per radian */
  470. X#define Abs( x )    ((x) < 0 ? -(x) : (x))
  471. X#define Max( a, b )    ((a) > (b) ? (a) : (b))
  472. X
  473. Xextern void    exit();
  474. X
  475. X#define    Printf    (void)printf
  476. X
  477. X#define    TOL    1.0e-10            /* tolerance for checks */
  478. X
  479. Xstatic int    errs = 0;        /* tally errors */
  480. X
  481. Xstatic void    CCheck(), RCheck();
  482. Xstatic double    RelDif();
  483. X
  484. X
  485. X/*ARGSUSED*/
  486. Xmain( argc, argv )
  487. X    int    argc;
  488. X    char    *argv[];
  489. X    {
  490. X    complex a, *bp, *cp;
  491. X
  492. X    /* CxAllo test */
  493. X    bp = CxAllo();
  494. X    if ( bp == NULL )
  495. X        {
  496. X        Printf( "CxAllo failed\n" );
  497. X        exit( 1 );
  498. X        }
  499. X
  500. X    /* CxReal, CxImag test */
  501. X    CxReal( bp ) = 1.0;
  502. X    CxImag( bp ) = 2.0;
  503. X    RCheck( "CxReal", CxReal( bp ), 1.0 );
  504. X    RCheck( "CxImag", CxImag( bp ), 2.0 );
  505. X
  506. X    /* CxCons test */
  507. X    cp = CxCons( &a, -3.0, -4.0);
  508. X    CCheck( "CxCons 1", a, -3.0, -4.0 );
  509. X    CCheck( "CxCons 2", *cp, -3.0, -4.0 );
  510. X
  511. X    /* CxNeg test */
  512. X    cp = CxNeg( &a );
  513. X    CCheck( "CxNeg 1", a, 3.0, 4.0 );
  514. X    CCheck( "CxNeg 2", *cp, 3.0, 4.0 );
  515. X
  516. X    /* CxCopy test */
  517. X    cp = CxCopy( bp, &a );
  518. X    (void)CxCons( &a, 1.0, sqrt( 3.0 ) );
  519. X    CCheck( "CxCopy 1", *bp, 3.0, 4.0 );
  520. X    CCheck( "CxCopy 2", *cp, 3.0, 4.0 );
  521. X
  522. X    /* CxAmpl, CxPhas test */
  523. X    RCheck( "CxAmpl 1", CxAmpl( &a ), 2.0 );
  524. X    RCheck( "CxPhas 1", CxPhas( &a ) * DEGRAD, 60.0 );
  525. X    /* try other quadrants */
  526. X    a.re = -a.re;
  527. X    RCheck( "CxAmpl 2", CxAmpl( &a ), 2.0 );
  528. X    RCheck( "CxPhas 2", CxPhas( &a ) * DEGRAD, 120.0 );
  529. X    a.im = -a.im;
  530. X    RCheck( "CxAmpl 3", CxAmpl( &a ), 2.0 );
  531. X    RCheck( "CxPhas 3", CxPhas( &a ) * DEGRAD, -120.0 );
  532. X    a.re = -a.re;
  533. X    RCheck( "CxAmpl 4", CxAmpl( &a ), 2.0 );
  534. X    RCheck( "CxPhas 4", CxPhas( &a ) * DEGRAD, -60.0 );
  535. X    /* one more for good measure */
  536. X    RCheck( "CxAmpl 5", CxAmpl( bp ), 5.0 );
  537. X
  538. X    /* CxPhsr test */
  539. X    cp = CxPhsr( &a, 100.0, -20.0 / DEGRAD );
  540. X    RCheck( "CxPhsr 1", CxAmpl( &a ), 100.0 );
  541. X    RCheck( "CxPhsr 2", CxPhas( &a ) * DEGRAD, -20.0 );
  542. X    RCheck( "CxPhsr 3", CxAmpl( cp ), 100.0 );
  543. X    RCheck( "CxPhsr 4", CxPhas( cp ) * DEGRAD, -20.0 );
  544. X
  545. X    /* CxConj test */
  546. X    cp = CxConj( bp );
  547. X    CCheck( "CxConj 1", *bp, 3.0, -4.0 );
  548. X    CCheck( "CxConj 2", *cp, 3.0, -4.0 );
  549. X
  550. X    /* CxScal test */
  551. X    cp = CxScal( bp, 2.0 );
  552. X    CCheck( "CxScal 1", *bp, 6.0, -8.0 );
  553. X    CCheck( "CxScal 2", *cp, 6.0, -8.0 );
  554. X
  555. X    /* CxAdd test */
  556. X    cp = CxAdd( CxCons( &a, -4.0, 11.0 ), bp );
  557. X    CCheck( "CxAdd 1", a, 2.0, 3.0 );
  558. X    CCheck( "CxAdd 2", *cp, 2.0, 3.0 );
  559. X
  560. X    /* CxSub test */
  561. X    cp = CxSub( CxCons( &a, 4.0, 7.0 ), bp );
  562. X    CCheck( "CxSub 1", a, -2.0, 15.0 );
  563. X    CCheck( "CxSub 2", *cp, -2.0, 15.0 );
  564. X
  565. X    /* CxMul test */
  566. X    cp = CxMul( CxCons( bp, -1.0, 3.0 ), CxCons( &a, 1.0, 2.0 ) );
  567. X    CCheck( "CxMul 1", *bp, -7.0, 1.0 );
  568. X    CCheck( "CxMul 2", *cp, -7.0, 1.0 );
  569. X
  570. X    /* CxDiv test */
  571. X    cp = CxDiv( bp, &a );
  572. X    CCheck( "CxDiv 1", *bp, -1.0, 3.0 );
  573. X    CCheck( "CxDiv 2", *cp, -1.0, 3.0 );
  574. X
  575. X    /* CxSqrt and overlapping CxMul tests */
  576. X    (void)CxCons( &a, -1.0, 2.0 );
  577. X    cp = CxSqrt( CxMul( &a, &a ) );
  578. X    CCheck( "CxSqrt 1", a, -1.0, 2.0 );
  579. X    CCheck( "CxSqrt 2", *cp, -1.0, 2.0 );
  580. X    (void)CxCons( &a, 3.0, 2.0 );
  581. X    cp = CxSqrt( CxMul( &a, &a ) );
  582. X    CCheck( "CxSqrt 3", a, 3.0, 2.0 );
  583. X    CCheck( "CxSqrt 4", *cp, 3.0, 2.0 );
  584. X
  585. X    /* CxFree "test" */
  586. X    CxFree( bp );
  587. X
  588. X    return errs;
  589. X    }
  590. X
  591. X
  592. Xstatic void
  593. XCCheck( s, c, r, i )            /* check complex number */
  594. X    char    *s;            /* message string for failure */
  595. X    complex    c;            /* complex to be checked */
  596. X    double    r, i;            /* expected real, imaginary parts */
  597. X    {
  598. X    if ( RelDif( CxReal( &c ), r ) > TOL
  599. X      || RelDif( CxImag( &c ), i ) > TOL
  600. X       )    {
  601. X        ++errs;
  602. X        Printf( "%s; s.b. (%f,%f), was (%g,%g)\n",
  603. X            s, r, i, c.re, c.im
  604. X              );
  605. X        }
  606. X    }
  607. X
  608. X
  609. Xstatic void
  610. XRCheck( s, d, r )            /* check real number */
  611. X    char    *s;            /* message string for failure */
  612. X    double    d;            /* real to be checked */
  613. X    double    r;            /* expected value */
  614. X    {
  615. X    if ( RelDif( d, r ) > TOL )
  616. X        {
  617. X        ++errs;
  618. X        Printf( "%s; s.b. %f, was %g\n", s, r, d );
  619. X        }
  620. X    }
  621. X
  622. X
  623. Xstatic double
  624. XRelDif( a, b )            /* returns relative difference:    */
  625. X    double    a, b;        /* 0.0 if exactly the same,
  626. X                   otherwise ratio of difference
  627. X                   to the larger of the two    */
  628. X    {
  629. X    double    c = Abs( a );
  630. X    double    d = Abs( b );
  631. X
  632. X    d = Max( c, d );
  633. X
  634. X    return d == 0.0 ? 0.0 : Abs( a - b ) / d;
  635. X    }
  636. END_OF_cx_test.c
  637. if test 4250 -ne `wc -c <cx_test.c`; then
  638.     echo shar: \"cx_test.c\" unpacked with wrong size!
  639. fi
  640. # end of overwriting check
  641. fi
  642. if test -f cxadd.c -a "${1}" != "-c" ; then 
  643.   echo shar: Will not over-write existing file \"cxadd.c\"
  644. else
  645. echo shar: Extracting \"cxadd.c\" \(304 characters\)
  646. sed "s/^X//" >cxadd.c <<'END_OF_cxadd.c'
  647. X/*
  648. X    CxAdd -- add one complex to another
  649. X
  650. X    last edit:    86/01/04    D A Gwyn
  651. X
  652. X    SCCS ID:    @(#)cxadd.c    1.1
  653. X
  654. X    CxAdd( &a, &b )    adds  b  to  a  and returns  &a
  655. X*/
  656. X
  657. X#include    <complex.h>
  658. X
  659. Xcomplex *
  660. XCxAdd( ap, bp )
  661. X    register complex    *ap, *bp;    /* may coincide */
  662. X    {
  663. X    ap->re += bp->re;
  664. X    ap->im += bp->im;
  665. X
  666. X    return ap;
  667. X    }
  668. END_OF_cxadd.c
  669. if test 304 -ne `wc -c <cxadd.c`; then
  670.     echo shar: \"cxadd.c\" unpacked with wrong size!
  671. fi
  672. # end of overwriting check
  673. fi
  674. if test -f cxampl.c -a "${1}" != "-c" ; then 
  675.   echo shar: Will not over-write existing file \"cxampl.c\"
  676. else
  677. echo shar: Extracting \"cxampl.c\" \(278 characters\)
  678. sed "s/^X//" >cxampl.c <<'END_OF_cxampl.c'
  679. X/*
  680. X    CxAmpl -- amplitude (magnitude, modulus, norm) of a complex
  681. X
  682. X    CxAmpl( &c )    returns  |c|
  683. X
  684. X    last edit:    86/01/04    D A Gwyn
  685. X
  686. X    SCCS ID:    @(#)cxampl.c    1.1
  687. X*/
  688. X
  689. X#include    <math.h>
  690. X
  691. X#include    <complex.h>
  692. X
  693. Xdouble
  694. XCxAmpl( cp )
  695. X    register complex    *cp;
  696. X    {
  697. X    return hypot( cp->re, cp->im );
  698. X    }
  699. END_OF_cxampl.c
  700. if test 278 -ne `wc -c <cxampl.c`; then
  701.     echo shar: \"cxampl.c\" unpacked with wrong size!
  702. fi
  703. # end of overwriting check
  704. fi
  705. if test -f cxconj.c -a "${1}" != "-c" ; then 
  706.   echo shar: Will not over-write existing file \"cxconj.c\"
  707. else
  708. echo shar: Extracting \"cxconj.c\" \(278 characters\)
  709. sed "s/^X//" >cxconj.c <<'END_OF_cxconj.c'
  710. X/*
  711. X    CxConj -- conjugate a complex
  712. X
  713. X    CxConj( &c )    conjugates  c  and returns  &c
  714. X
  715. X    last edit:    86/01/04    D A Gwyn
  716. X
  717. X    SCCS ID:    @(#)cxconj.c    1.1
  718. X*/
  719. X
  720. X#include    <complex.h>
  721. X
  722. Xcomplex *
  723. XCxConj( cp )
  724. X    register complex    *cp;
  725. X    {
  726. X    /* (real part unchanged) */
  727. X    cp->im = -cp->im;
  728. X
  729. X    return cp;
  730. X    }
  731. END_OF_cxconj.c
  732. if test 278 -ne `wc -c <cxconj.c`; then
  733.     echo shar: \"cxconj.c\" unpacked with wrong size!
  734. fi
  735. # end of overwriting check
  736. fi
  737. if test -f cxcons.c -a "${1}" != "-c" ; then 
  738.   echo shar: Will not over-write existing file \"cxcons.c\"
  739. else
  740. echo shar: Extracting \"cxcons.c\" \(329 characters\)
  741. sed "s/^X//" >cxcons.c <<'END_OF_cxcons.c'
  742. X/*
  743. X    CxCons -- construct a complex from real and imaginary parts
  744. X
  745. X    CxCons( &c, re, im )    makes  c = re + i im  and returns  &c
  746. X
  747. X    last edit:    86/01/04    D A Gwyn
  748. X
  749. X    SCCS ID:    @(#)cxcons.c    1.1
  750. X*/
  751. X
  752. X#include    <complex.h>
  753. X
  754. Xcomplex *
  755. XCxCons( cp, re, im )
  756. X    register complex    *cp;
  757. X    double            re, im;
  758. X    {
  759. X    cp->re = re;
  760. X    cp->im = im;
  761. X
  762. X    return cp;
  763. X    }
  764. END_OF_cxcons.c
  765. if test 329 -ne `wc -c <cxcons.c`; then
  766.     echo shar: \"cxcons.c\" unpacked with wrong size!
  767. fi
  768. # end of overwriting check
  769. fi
  770. if test -f cxcopy.c -a "${1}" != "-c" ; then 
  771.   echo shar: Will not over-write existing file \"cxcopy.c\"
  772. else
  773. echo shar: Extracting \"cxcopy.c\" \(264 characters\)
  774. sed "s/^X//" >cxcopy.c <<'END_OF_cxcopy.c'
  775. X/*
  776. X    CxCopy -- copy a complex
  777. X
  778. X    last edit:    86/01/04    D A Gwyn
  779. X
  780. X    SCCS ID:    @(#)cxcopy.c    1.1
  781. X
  782. X    CxCopy( &a, &b )    copies  b  to  a  and returns  &a
  783. X*/
  784. X
  785. X#include    <complex.h>
  786. X
  787. Xcomplex *
  788. XCxCopy( ap, bp )
  789. X    complex    *ap, *bp;        /* may coincide */
  790. X    {
  791. X    *ap = *bp;
  792. X
  793. X    return ap;
  794. X    }
  795. END_OF_cxcopy.c
  796. if test 264 -ne `wc -c <cxcopy.c`; then
  797.     echo shar: \"cxcopy.c\" unpacked with wrong size!
  798. fi
  799. # end of overwriting check
  800. fi
  801. if test -f cxdiv.c -a "${1}" != "-c" ; then 
  802.   echo shar: Will not over-write existing file \"cxdiv.c\"
  803. else
  804. echo shar: Extracting \"cxdiv.c\" \(820 characters\)
  805. sed "s/^X//" >cxdiv.c <<'END_OF_cxdiv.c'
  806. X/*
  807. X    CxDiv -- divide one complex by another
  808. X
  809. X    CxDiv( &a, &b )    divides  a  by  b  and returns  &a;
  810. X            zero divisor fails
  811. X
  812. X    last edit:    86/01/04    D A Gwyn
  813. X
  814. X    SCCS ID:    @(#)cxdiv.c    1.1 (modified for public version)
  815. X*/
  816. X
  817. X#include    <complex.h>
  818. X
  819. X#define Abs( x )    ((x) < 0 ? -(x) : (x))
  820. X
  821. Xcomplex *
  822. XCxDiv( ap, bp )
  823. X    register complex    *ap, *bp;    /* may coincide (?) */
  824. X    {
  825. X    double    r, s;
  826. X    double    ap__re = ap->re;
  827. X
  828. X    /* Note: classical formula may cause unnecessary overflow */
  829. X    r = bp->re;
  830. X    s = bp->im;
  831. X    if ( Abs( r ) >= Abs( s ) )
  832. X        {
  833. X        r = s / r;        /* <= 1 */
  834. X        s = bp->re + r * s;
  835. X        ap->re = (ap->re + ap->im * r) / s;
  836. X        ap->im = (ap->im - ap__re * r) / s;
  837. X        }
  838. X    else /* Abs( s ) > Abs( r ) */
  839. X        {
  840. X        r = r / s;        /* < 1 */
  841. X        s = s + r * bp->re;
  842. X        ap->re = (ap->re * r + ap->im) / s;
  843. X        ap->im = (ap->im * r - ap__re) / s;
  844. X        }
  845. X
  846. X    return ap;
  847. X    }
  848. END_OF_cxdiv.c
  849. if test 820 -ne `wc -c <cxdiv.c`; then
  850.     echo shar: \"cxdiv.c\" unpacked with wrong size!
  851. fi
  852. # end of overwriting check
  853. fi
  854. if test -f cxmul.c -a "${1}" != "-c" ; then 
  855.   echo shar: Will not over-write existing file \"cxmul.c\"
  856. else
  857. echo shar: Extracting \"cxmul.c\" \(424 characters\)
  858. sed "s/^X//" >cxmul.c <<'END_OF_cxmul.c'
  859. X/*
  860. X    CxMul -- multiply one complex by another
  861. X
  862. X    CxMul( &a, &b )    multiplies  a  by  b  and returns  &a
  863. X
  864. X    last edit:    86/01/04    D A Gwyn
  865. X
  866. X    SCCS ID:    @(#)cxmul.c    1.1
  867. X*/
  868. X
  869. X#include    <complex.h>
  870. X
  871. Xcomplex *
  872. XCxMul( ap, bp )
  873. X    register complex    *ap, *bp;    /* (may coincide) */
  874. X    {
  875. X    double            ap__re = ap->re;
  876. X    double            bp__re = bp->re;
  877. X
  878. X    ap->re = ap__re * bp__re - ap->im * bp->im;
  879. X    ap->im = ap__re * bp->im + ap->im * bp__re;
  880. X
  881. X    return ap;
  882. X    }
  883. END_OF_cxmul.c
  884. if test 424 -ne `wc -c <cxmul.c`; then
  885.     echo shar: \"cxmul.c\" unpacked with wrong size!
  886. fi
  887. # end of overwriting check
  888. fi
  889. if test -f cxphas.c -a "${1}" != "-c" ; then 
  890.   echo shar: Will not over-write existing file \"cxphas.c\"
  891. else
  892. echo shar: Extracting \"cxphas.c\" \(406 characters\)
  893. sed "s/^X//" >cxphas.c <<'END_OF_cxphas.c'
  894. X/*
  895. X    CxPhas -- phase (angle, argument) of a complex
  896. X
  897. X    CxPhas( &c )    returns  arg(c)  in radians (-Pi,Pi]
  898. X
  899. X    last edit:    86/01/04    D A Gwyn
  900. X
  901. X    SCCS ID:    @(#)cxphas.c    1.1 (modified for public version)
  902. X*/
  903. X
  904. X#include    <math.h>
  905. X
  906. X#include    <complex.h>
  907. X
  908. Xdouble
  909. XCxPhas( cp )
  910. X    register complex    *cp;
  911. X    {
  912. X    if ( cp->re == 0.0 && cp->im == 0.0 )
  913. X        return 0.0;        /* can't trust atan2() */
  914. X    else
  915. X        return atan2( cp->im, cp->re );
  916. X    }
  917. END_OF_cxphas.c
  918. if test 406 -ne `wc -c <cxphas.c`; then
  919.     echo shar: \"cxphas.c\" unpacked with wrong size!
  920. fi
  921. # end of overwriting check
  922. fi
  923. if test -f cxphsr.c -a "${1}" != "-c" ; then 
  924.   echo shar: Will not over-write existing file \"cxphsr.c\"
  925. else
  926. echo shar: Extracting \"cxphsr.c\" \(395 characters\)
  927. sed "s/^X//" >cxphsr.c <<'END_OF_cxphsr.c'
  928. X/*
  929. X    CxPhsr -- construct a complex "phasor" from amplitude and phase
  930. X
  931. X    CxPhsr( &c, amp, phs )    makes  c = amp exp(i phs)
  932. X                    and returns  &c
  933. X
  934. X    last edit:    86/01/04    D A Gwyn
  935. X
  936. X    SCCS ID:    @(#)cxphsr.c    1.1
  937. X*/
  938. X
  939. X#include    <math.h>
  940. X
  941. X#include    <complex.h>
  942. X
  943. Xcomplex *
  944. XCxPhsr( cp, amp, phs )
  945. X    register complex    *cp;
  946. X    double            amp, phs;
  947. X    {
  948. X    cp->re = amp * cos( phs );
  949. X    cp->im = amp * sin( phs );
  950. X
  951. X    return cp;
  952. X    }
  953. END_OF_cxphsr.c
  954. if test 395 -ne `wc -c <cxphsr.c`; then
  955.     echo shar: \"cxphsr.c\" unpacked with wrong size!
  956. fi
  957. # end of overwriting check
  958. fi
  959. if test -f cxscal.c -a "${1}" != "-c" ; then 
  960.   echo shar: Will not over-write existing file \"cxscal.c\"
  961. else
  962. echo shar: Extracting \"cxscal.c\" \(291 characters\)
  963. sed "s/^X//" >cxscal.c <<'END_OF_cxscal.c'
  964. X/*
  965. X    CxScal -- multiply a complex by a scalar
  966. X
  967. X    CxScal( &c, s )    scales  c  by  s  and returns  &c
  968. X
  969. X    last edit:    86/01/04    D A Gwyn
  970. X
  971. X    SCCS ID:    @(#)cxscal.c    1.1
  972. X*/
  973. X
  974. X#include    <complex.h>
  975. X
  976. Xcomplex *
  977. XCxScal( cp, s )
  978. X    register complex    *cp;
  979. X    double            s;
  980. X    {
  981. X    cp->re *= s;
  982. X    cp->im *= s;
  983. X
  984. X    return cp;
  985. X    }
  986. END_OF_cxscal.c
  987. if test 291 -ne `wc -c <cxscal.c`; then
  988.     echo shar: \"cxscal.c\" unpacked with wrong size!
  989. fi
  990. # end of overwriting check
  991. fi
  992. if test -f cxsqrt.c -a "${1}" != "-c" ; then 
  993.   echo shar: Will not over-write existing file \"cxsqrt.c\"
  994. else
  995. echo shar: Extracting \"cxsqrt.c\" \(1339 characters\)
  996. sed "s/^X//" >cxsqrt.c <<'END_OF_cxsqrt.c'
  997. X/*
  998. X    CxSqrt -- compute square root of complex number
  999. X
  1000. X    CxSqrt( &c )    replaces  c  by  sqrt(c)  and returns  &c
  1001. X
  1002. X    Note:    This is a double-valued function; the result of
  1003. X        CxSqrt() always has nonnegative imaginary part.
  1004. X
  1005. X    inspired by Jeff Hanes' version
  1006. X
  1007. X    last edit:    86/01/04    D A Gwyn
  1008. X
  1009. X    SCCS ID:    @(#)cxsqrt.c    1.1 (modified for public version)
  1010. X*/
  1011. X
  1012. X#include    <math.h>
  1013. X
  1014. X#include    <complex.h>
  1015. X
  1016. X#define    Sgn( x )    ((x) == 0 ? 0 : (x) > 0 ? 1 : -1)
  1017. X
  1018. Xcomplex *
  1019. XCxSqrt( cp )
  1020. X    register complex    *cp;
  1021. X    {
  1022. X    /* record signs of original real & imaginary parts */
  1023. X    int            re_sign = Sgn( cp->re );
  1024. X    int            im_sign = Sgn( cp->im );
  1025. X
  1026. X    /* special cases are not necessary; they are here for speed */
  1027. X
  1028. X    if ( re_sign == 0 )
  1029. X        if ( im_sign == 0 )
  1030. X            ;        /* (0,0) already there */
  1031. X        else if ( im_sign > 0 )
  1032. X            cp->re = cp->im = sqrt( cp->im / 2.0 );
  1033. X        else            /* im_sign < 0 */
  1034. X            cp->re = -(cp->im = sqrt( -cp->im / 2.0 ));
  1035. X    else if ( im_sign == 0 )
  1036. X        if ( re_sign > 0 )
  1037. X            cp->re = sqrt( cp->re );
  1038. X/*            cp->im = 0.0;    /* 0 already there */
  1039. X        else    {        /* re_sign < 0 */
  1040. X            cp->im = sqrt( -cp->re );
  1041. X            cp->re = 0.0;
  1042. X            }
  1043. X    else    {            /* no shortcuts */
  1044. X        double    ampl = CxAmpl( cp );
  1045. X
  1046. X        cp->im = sqrt( (ampl - cp->re) /2.0 );
  1047. X
  1048. X        if ( im_sign > 0 )
  1049. X            cp->re = sqrt( (ampl + cp->re) / 2.0 );
  1050. X        else            /* im_sign < 0 */
  1051. X            cp->re = -sqrt( (ampl + cp->re) / 2.0 );
  1052. X        }
  1053. X
  1054. X    return cp;
  1055. X    }
  1056. END_OF_cxsqrt.c
  1057. if test 1339 -ne `wc -c <cxsqrt.c`; then
  1058.     echo shar: \"cxsqrt.c\" unpacked with wrong size!
  1059. fi
  1060. # end of overwriting check
  1061. fi
  1062. if test -f cxsub.c -a "${1}" != "-c" ; then 
  1063.   echo shar: Will not over-write existing file \"cxsub.c\"
  1064. else
  1065. echo shar: Extracting \"cxsub.c\" \(320 characters\)
  1066. sed "s/^X//" >cxsub.c <<'END_OF_cxsub.c'
  1067. X/*
  1068. X    CxSub -- subtract one complex from another
  1069. X
  1070. X    CxSub( &a, &b )    subtracts  b  from  a  and returns  &a
  1071. X
  1072. X    last edit:    86/01/04    D A Gwyn
  1073. X
  1074. X    SCCS ID:    @(#)cxsub.c    1.1
  1075. X*/
  1076. X
  1077. X#include    <complex.h>
  1078. X
  1079. Xcomplex *
  1080. XCxSub( ap, bp )
  1081. X    register complex    *ap, *bp;    /* (may coincide) */
  1082. X    {
  1083. X    ap->re -= bp->re;
  1084. X    ap->im -= bp->im;
  1085. X
  1086. X    return ap;
  1087. X    }
  1088. END_OF_cxsub.c
  1089. if test 320 -ne `wc -c <cxsub.c`; then
  1090.     echo shar: \"cxsub.c\" unpacked with wrong size!
  1091. fi
  1092. # end of overwriting check
  1093. fi
  1094. echo shar: End of shell archive.
  1095. exit 0
  1096. -- 
  1097.  
  1098. Rich $alz            "Anger is an energy"
  1099. Cronus Project, BBN Labs    rsalz@bbn.com
  1100. Moderator, comp.sources.unix    sources@uunet.uu.net
  1101. -- 
  1102.  
  1103. Rich $alz            "Anger is an energy"
  1104. Cronus Project, BBN Labs    rsalz@bbn.com
  1105. Moderator, comp.sources.unix    sources@uunet.uu.net
  1106.